package com.tjtt.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class SFtpUtil {

	private String host = "";
	private String username = "";
	private String password = "";
	private int port = 0;
	private ChannelSftp sftp = null;
	private String localPath = "";
	private String remotePath = "";
	private String fileListPath = "";
	private final String seperator = File.separator;
	
	private static Logger logger = Logger.getLogger(SFtpUtil.class);

	/**
	 * connect server via sftp
	 */
	public void connect(String host, int port, String username,String password) {
		try {
			if (sftp != null) {
				logger.info("上次sftp连接未关闭");
			}
			JSch jsch = new JSch();
			jsch.getSession(username, host, port);
			Session sshSession = jsch.getSession(username, host, port);
			logger.info("Session已创建.");
			sshSession.setPassword(password);
			Properties sshConfig = new Properties();
			sshConfig.put("StrictHostKeyChecking", "no");
			sshSession.setConfig(sshConfig);
			sshSession.connect();
			logger.info("Session已连接.");
			logger.info("打开文件传输通道.");
			Channel channel = sshSession.openChannel("sftp");
			channel.connect();
			sftp = (ChannelSftp) channel;
			logger.info(sftp.getHome());
			logger.info("与[ " + host + "]sftp已连接.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Disconnect with server
	 */
	public void disconnect() {
		if (this.sftp != null) {
			if (this.sftp.isConnected()) {
				this.sftp.disconnect();
				logger.info("连接关闭成功");
			} else if (this.sftp.isClosed()) {
				logger.info("连接已关闭");
			}
		}

	}
	
	/**
	 * 下载文件
	 * @param remoteFile 远程文件名,文件夹使用"/"分割
	 * @param saveAsFile 另存为本地文件名及路径
	 * @return 0 成功,1找不到远程文件,2找不到本地文件,3其他错误
	 * 刘元华
	 * 2010-11-8下午05:49:15
	 */
	public String download(String remoteFile,String saveAsFile) {
		String returnString = "0";
		logger.info("开始下载文件"+saveAsFile);
		File file = new File(saveAsFile);
		File parentFile = new File(file.getParent());
		if(parentFile==null||!parentFile.exists()){
			parentFile.mkdirs();
		}
		try {
			this.sftp.get(remoteFile, new FileOutputStream(file));
		} catch (FileNotFoundException e) {
			logger.error("下载文件失败"+saveAsFile);
			returnString = "2";
		} catch (SftpException e) {
			logger.error("下载文件失败"+saveAsFile);
			if("No such file".equals(e.getMessage())){
				returnString = "1";
			} else {
				returnString = "3";
			}
		}
		logger.info("文件下载成功"+saveAsFile);
		return returnString;	
	}

	/**
	 * 上传文件-批量
	 * @param localPath 本地路径
	 * @param remotePath 远程路径
	 * @param fileListPath 文件列表
	 * 刘元华
	 * 2010-11-8下午04:12:58
	 */
	public void upload(String localPath,String remotePath,List<String> fileList) {
		try {
			if (fileList != null) {
				for (String fileName : fileList) {
					String localFile = localPath + this.seperator + fileName;
					File file = new File(localFile);
					if (file.isFile()) {
						String remoteFile = remotePath + "/"+ fileName;
						File rfile = new File(remoteFile);
						String rpath = rfile.getParent().replace("\\", "/").replace("//", "/");
						try {
							createDir(rpath, sftp);
						} catch (Exception e) {
							logger.error("上传文件失败" + rpath);
						}
						this.sftp.put(new FileInputStream(file), file.getName());
						logger.info("上传文件成功 " + rpath);
					}
				}
			}
		} catch (FileNotFoundException e) {
			logger.error("上传文件失败");
		} catch (SftpException e) {
			logger.error("上传文件失败");
		}

	}
	
	/**
	  * 上传文件-单个
	 * @param localFileName 本地文件
	 * @param remoteFileName 远程文件,使用"/"分割
	 * @return 0 成功,1找不到远程文件,2找不到本地文件,3其他错误，4本地文件是目录
	 * 刘元华
	 * 2010-11-8下午06:11:44
	 */
	public String upload(String localFileName,String remoteFileName) {
		String returnString = "0";
		try {
			File file = new File(localFileName);
			if(!file.exists()){
				logger.error("上传文件失败" + localFileName);
				returnString = "2";
			}else if (file.isFile()) {
				File rfile = new File(remoteFileName);
				String rpath = rfile.getParent().replace("\\", "/").replace("//", "/");
				try {
					createDir(rpath, sftp);
				} catch (Exception e) {
					returnString = "3";
					logger.error("上传文件失败" + localFileName);
				}
				this.sftp.put(new FileInputStream(file), rfile.getName());
				logger.info("上传文件成功" + localFileName);
			} else {
				logger.error("上传文件失败" + localFileName);
				returnString = "4";
			}
		} catch (FileNotFoundException e) {
			returnString = "2";
		} catch (SftpException e) {
			if("No such file".equals(e.getMessage())){
				returnString = "1";
			} else {
				returnString = "3";
			}
		}
		return returnString;
	}
	
	/**
	 * 删除本地和远程文件
	  * @param localFileName 本地文件
	 * @param remoteFileName 远程文件,使用"/"分割
	 * @return 0 成功,1找不到远程文件,2找不到本地文件,3其他错误,4本地文件是目录
	 * 刘元华
	 * 2010-11-8下午06:21:18
	 */
	public String delete(String localFileName,String remoteFileName){
		String returnString = "0";
		try {
			File file = new File(localFileName);
			if (file.isFile()) {
				this.sftp.rm(remoteFileName);
				logger.info("删除远程文件成功"+remoteFileName);
				file.delete();
				logger.info("删除本地文件成功"+localFileName);
			} else {
				logger.error("删除本地文件失败" + localFileName);
				returnString = "4";
			}
		}catch (SftpException e) {
			logger.error("删除远程文件失败"+remoteFileName);
			if("No such file".equals(e.getMessage())){
				returnString = "1";
			} else {
				returnString = "3";
			}
		}
		return returnString;
	}
	
	/**
	 * 删除本地文件
	  * @param localFileName 本地文件
	 * 刘元华
	 * 2010-11-8下午06:21:18
	 */
	public String deleteLocal(String localFileName){
		String returnString = "0";
		File file = new File(localFileName);
		if (file.isFile()) {
			file.delete();
			logger.info("删除本地文件成功" + localFileName);
		} else {
			logger.error("删除本地文件失败" + localFileName);
		}
		return returnString;
	}
	
	/**
	 * 删除远程文件
	 * @param remoteFileName 远程文件,使用"/"分割
	 * @return 0 成功,1找不到远程文件,2找不到本地文件,3其他错误
	 * 刘元华
	 * 2010-11-8下午06:21:18
	 */
	public String deleteRemote(String remoteFileName){
		String returnString = "0";
		try {
			this.sftp.rm(remoteFileName);
			logger.info("删除文件成功" + remoteFileName);
		}catch (SftpException e) {
			logger.error("删除文件失败" + remoteFileName);
			if("No such file".equals(e.getMessage())){
				returnString = "1";
			} else {
				returnString = "3";
			}
		}
		return returnString;
	}

	/**
	 * 建立文件目录，若有则进入。
	 * 
	 * @param filepath
	 * @param sftp
	 */
	private void createDir(String filepath, ChannelSftp sftp) {
		boolean bcreated = false;
		boolean bparent = false;
		File file = new File(filepath);
		String ppath = file.getParent().replace("\\", "/").replace("//", "/");
		try {
			this.sftp.cd(ppath);
			bparent = true;
		} catch (SftpException e1) {
			bparent = false;
		}
		try {
			if (bparent) {
				try {
					this.sftp.cd(filepath);
					bcreated = true;
				} catch (Exception e) {
					bcreated = false;
				}
				if (!bcreated) {
					this.sftp.mkdir(filepath);
					bcreated = true;
				}
				return;
			} else {
				createDir(ppath, sftp);
				this.sftp.cd(ppath);
				this.sftp.mkdir(filepath);
			}
		} catch (SftpException e) {
			logger.info("mkdir failed :" + filepath);
		}

		try {
			this.sftp.cd(filepath);
		} catch (SftpException e) {
			logger.info("can not cd into :" + filepath);
		}

	}

	/**
	 * @return the host
	 */
	public String getHost() {
		return host;
	}

	/**
	 * @param host
	 *            the host to set
	 */
	public void setHost(String host) {
		this.host = host;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username
	 *            the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the port
	 */
	public int getPort() {
		return port;
	}

	/**
	 * @param port
	 *            the port to set
	 */
	public void setPort(int port) {
		this.port = port;
	}

	/**
	 * @return the sftp
	 */
	public ChannelSftp getSftp() {
		return sftp;
	}

	/**
	 * @param sftp
	 *            the sftp to set
	 */
	public void setSftp(ChannelSftp sftp) {
		this.sftp = sftp;
	}

	/**
	 * @return the localPath
	 */
	public String getLocalPath() {
		return localPath;
	}

	/**
	 * @param localPath
	 *            the localPath to set
	 */
	public void setLocalPath(String localPath) {
		this.localPath = localPath;
	}

	/**
	 * @return the remotePath
	 */
	public String getRemotePath() {
		return remotePath;
	}

	/**
	 * @param remotePath
	 *            the remotePath to set
	 */
	public void setRemotePath(String remotePath) {
		this.remotePath = remotePath;
	}

	/**
	 * @return the fileListPath
	 */
	public String getFileListPath() {
		return fileListPath;
	}

	/**
	 * @param fileListPath
	 *            the fileListPath to set
	 */
	public void setFileListPath(String fileListPath) {
		this.fileListPath = fileListPath;
	}

	public static void main(String[] args) {
		SFtpUtil ftp = new SFtpUtil();
		ftp.connect("125.35.1.245", 22, "oracle", "cqcoracle");
		List<String> fileList = new ArrayList<String>();
		fileList.add("KeyGen.java");
		fileList.add("PortForwardingR.java");
		ftp.upload("D:\\TDDOWNLOAD\\jsch-0.1.44\\examples\\KeyGen.java","/parafile/inspection/2010/11/08/KeyGen1.java");
		ftp.download("/parafile/inspection/2010/11/08/KeyGen1.java", "D:\\TDDOWNLOAD\\0jsch-0.1.44\\examples\\KeyGen1.java");
		ftp.delete("D:\\TDDOWNLOAD\\0jsch-0.1.44\\examples\\KeyGen1.java","/parafile/inspection/2010/11/08/KeyGen.java");
		ftp.disconnect();
		System.exit(0);
	}

}
